home *** CD-ROM | disk | FTP | other *** search
- /* MailCarrier.m
-
- See the .h file for additional notes.
- Written in January 1991 by Eric Celeste.
- */
-
- #import "MailCarrier.h"
- #import <stdio.h>
- #import <stdlib.h>
- #import <strings.h>
- #import <mach.h>
- #import <mach_interface.h>
- #import <appkit/Application.h>
- #import <appkit/Control.h>
- #import <appkit/Listener.h>
- #import <appkit/Pasteboard.h>
-
- @implementation MailCarrier
-
- /* Note that init gets called too early in the process of the
- application's launch to let us set up the listener right here.
- Thus, we make ourself a delegate of the application here, and
- then take care of the listener later, once the application
- is done launching.
- */
- - init
- {
- [super init];
-
- [NXApp setDelegate:self];
-
- return self;
- }
-
- /* Now it is late enough for the listener to be ready to deal with
- our demands. Here we make sure the listener knows to send us
- all the messages meant for services. While we are here, we also
- make sure that the recipient field is set up to point back to
- the user (since I assume this service will often be used to
- archive stuff into the users own mail).
- */
- - appDidInit:sender
- {
- [[NXApp appListener] setServicesDelegate:self];
- [recipient setStringValue:NXUserName()];
-
- return self;
- }
-
- /* This is the heart of my service. It gets quite messy, but it
- seems that most of this mess is really needed. In particular,
- it is vital that "types" gets called before "readType:data:length:"
- or else the pasteboard will never do the right thing.
- */
- - carryMail:myPasteboard userData:(const char *)userData error:(char **)message
- {
- const NXAtom *myTypes; /* absorbs the result of types message */
- char *data; /* data returned by the pasteboard */
- int length; /* length of data returned by the pasteboard */
- char *text; /* holds copy of data from the pasteboard */
- const char *name; /* holds a pointer to the user's name */
- FILE *stream; /* our connection to the outside world */
- char *command; /* the command string we send outside */
-
- myTypes = [myPasteboard types];
-
- if ([myPasteboard readType:NXAsciiPboardType data:&data length:&length]) {
-
- /* this bit of work ensures there is a null at the text's end */
- text = malloc(length+1);
- strncpy(text, data, length);
- text[length]='\0';
-
- /* let the user know what has been sent */
- [content setStringValue:(const char *)text];
-
- /* make room for and create command using the name at the outlet */
- command = malloc(20 + strlen(name = [recipient stringValue]));
- strcpy(command,"/usr/lib/sendmail ");
- strcat(command,name);
-
- /* here is where we send the command out to unix */
- stream = popen((const char *)command,"w");
- if (stream) {
- /* and we put the message into the command's standard input */
- fputs((const char *)text, stream);
- pclose(stream);
- /* this is a small signal to the user that all went well */
- [notes setIntValue:++numberOfMessages];
- } else {
- /* and this signals that all went not-so-well */
- [notes setStringValue:"Failed to allocate the stream!"];
- }
-
- /* don't forget to let go of memory */
- free(text);
- /* use vm_deallocate since readType above used Mach to allocate */
- vm_deallocate(task_self(), (vm_address_t)data, (vm_size_t)length);
-
- } else {
-
- /* making sure the user is not misled about our failure */
- [content setStringValue:""];
- [notes setStringValue:"Failed to read the pasteboard!"];
-
- }
-
- return self;
- }
-
- @end
-